#include "ipc/ipc_value.h"

IPC_Value *ipc_value_create_by_cef_value(cef_value_t *value) {
    cef_value_type_t type = value->get_type(value);
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    if (type == VTYPE_BOOL) {
        ipc_value->type = IPC_TYPE_BOOL;
        ipc_value->value.Bool = value->get_bool(value);
    } else if (type == VTYPE_INT) {
        ipc_value->type = IPC_TYPE_INT;
        ipc_value->value.Int = value->get_int(value);
    } else if (type == VTYPE_DOUBLE) {
        ipc_value->type = IPC_TYPE_DOUBLE;
        ipc_value->value.Double = value->get_double(value);
    } else if (type == VTYPE_STRING) {
        ipc_value->type = IPC_TYPE_STRING;
        cef_string_userfree_t string = value->get_string(value);
        cef_string_utf8_t utf8s = {};
        cef_string_utf16_to_utf8(string->str, string->length, &utf8s);
        // ipc_value->value.String = utf8s.str;
        ipc_value_set_string(ipc_value, utf8s.str);
        cef_string_userfree_free(string);
        cef_string_utf8_clear(&utf8s);
    } else {
        free(ipc_value);
        LOG_INFO("cef_value type to IPC value type error");
        return NULL;
    }
    LOG_DEBUG("cef_value type to IPC value type end");
    return ipc_value;
}


cef_value_t *ipc_value_to_cef_value(IPC_Value *ipc_value) {
    cef_value_t *cef_value = cef_value_create();
    if (ipc_value) {
        IPC_Value_Type type = ipc_value->type;
        if (type == IPC_TYPE_BOOL) {
            cef_value->set_bool(cef_value, ipc_value->value.Bool);
        } else if (type == IPC_TYPE_DOUBLE) {
            cef_value->set_double(cef_value, ipc_value->value.Double);
        } else if (type == IPC_TYPE_INT) {
            cef_value->set_int(cef_value, ipc_value->value.Int);
        } else if (type == IPC_TYPE_STRING) {
            cef_string_t cef_string = {};
            cef_string_utf8_to_utf16(ipc_value->value.String, strlen(ipc_value->value.String), &cef_string);
            cef_value->set_string(cef_value, &cef_string);
            cef_string_clear(&cef_string);
        } else {
            cef_value->base.release(&cef_value->base);
            LOG_INFO("IPC value to cef_value type  type error");
            return NULL;
        }
    }
    return cef_value;
}

void ipc_value_set_string(IPC_Value *ipc_value, char *str) {
    ipc_value->type = IPC_TYPE_STRING;
    ipc_value->value.String = strdup(str);
}

void ipc_value_free(IPC_Value *ipc_value) {
    if (ipc_value->type == IPC_TYPE_STRING && ipc_value->value.String != NULL) {
        free(ipc_value->value.String);
    }
    free(ipc_value);
}

IPC_Value *_create_ipc_value_int(int value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_INT;
    ipc_value->value.Int = value;
}

IPC_Value *_create_ipc_value_double(double value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_DOUBLE;
    ipc_value->value.Double = value;
}

IPC_Value *_create_ipc_value_bool(int value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_BOOL;
    ipc_value->value.Bool = value;
}
IPC_Value *_create_ipc_value_string(char *value) {
    IPC_Value *ipc_value = (IPC_Value *)malloc(sizeof(IPC_Value));
    ipc_value->type = IPC_TYPE_STRING;
    ipc_value_set_string(ipc_value, value);
}

int _ipc_value_get_int(IPC_Value *ipc_value) { return ipc_value->value.Int; }

double _ipc_value_get_double(IPC_Value *ipc_value) { return ipc_value->value.Double; }

char *_ipc_value_get_string(IPC_Value *ipc_value) { return ipc_value->value.String; }

int _ipc_value_get_bool(IPC_Value *ipc_value) { return ipc_value->value.Bool; }

IPC_Value_Type _ipc_value_get_type(IPC_Value *ipc_value) { return ipc_value->type; }